﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Simulator;

namespace ModelConfigurator
{
    public partial class FormResource : FormBase
    {
        /// <summary>
        /// Список категорий, для каждой из которых есть список атомарных ресурсов
        /// </summary>
        public SortedList<string,List<AtomicRes>> Categories{ get; set;}
        /// <summary>
        /// Редактируемый блок Ресурс
        /// </summary>
        public Resource Edited{get; set;}
        /// <summary>
        /// Список имен параметров, загруженный из БД
        /// </summary>
        public List<string> ParamNames { get; set; }

        public FormResource()
        {
            InitializeComponent();
        }

        private void FormResource_Load(object sender, EventArgs e)
        {
            //*************ПРИМЕР НА ЗАПОЛНЕНИЕ Categories
            /*Categories = new SortedList<string, List<AtomicRes>>();
            List<AtomicRes> lar = new List<AtomicRes>();
            AtomicRes a = new AtomicRes();
            string cat = "Пользователь";
            a.Category = cat;
            a.Name = "Инженер 2 к";
            lar.Add(a); a = new AtomicRes();
            a.Category = cat;
            a.Name = "Инженер 1 к";
            lar.Add(a); a = new AtomicRes();
            Categories.Add(cat, lar);
            lar = new List<AtomicRes>();
            cat = "Прикладное ПО";
            a.Category = cat;
            a.Name = "Altium Designer";
            lar.Add(a); a = new AtomicRes();
            a.Category = cat;
            a.Name = "OrCAD";
            lar.Add(a);
            Categories.Add(cat, lar);*/
            //**************КОНЕЦ ПРИМЕРА***************


            ImageList lst = new ImageList();

            lst.Images.Add(ModelConfigurator.Properties.Resources.small_database);//загрузим картинку "база данных"
            lst.Images.Add(ModelConfigurator.Properties.Resources.small_resources);//загрузим картинку для ресурсов
            lst.Images.Add(ModelConfigurator.Properties.Resources.small_folder);//загрузим картинку для категорий
            
            
            treeViewAtomic.ImageList = lst;
           
            TreeNode[] catNode = null;//узлы категории
            TreeNode[] resNode = null;//узлы ресурсов 1-й категории
            string s;
            catNode = new TreeNode[Categories.Count];
            for(int i=0;i<Categories.Count;i++)
            {
                s = Categories.Keys[i];
                resNode = new TreeNode[Categories[s].Count];//иниц. массив ресурсов категории s
                for(int j=0;j<Categories[s].Count;j++)
                {
                    resNode[j] = new TreeNode(Categories[s][j].Name,1,1);//добавим j-й узел
                    resNode[j].Name = "AtomicNode" + j;
                }
                catNode[i] = new TreeNode(s,2,2,resNode);
                catNode[i].Name = "CatNode" + i;
                
            }
            TreeNode rootNode = new TreeNode("База данных",0,0,catNode);
            treeViewAtomic.Nodes.Add(rootNode);
            
            //теперь инициализируем поля
            textBoxText.Text = Edited.Text;
            numericUpDown1.Value = Convert.ToDecimal(Edited.Multiplicity);

            //настроим dataGridView
            //добавим только те доп. параметры, у кот. есть имя
            DataGridViewTextBoxColumn col;
            string p;
            for(int i=0;i< ParamNames.Count; i++)
            {
                p = ParamNames[i];//имя параметра 
                col = new DataGridViewTextBoxColumn();
                col.Name = "ColumnParam" + i;
                col.HeaderText = p;
                if (ParamNames[i] == "")
                    col.Visible = false;
                //добавим одинаковую колонку в обе таблицы
                dataGridView1.Columns.Add(col);

                col = new DataGridViewTextBoxColumn();
                col.Name = "colParam" + i;
                col.HeaderText = p;
                if (ParamNames[i] == "")
                    col.Visible = false;
                dataGridView2.Columns.Add(col);

            }
            //заполним вторую таблицу
            AtomicRes ar;
            for (int i = 0; i < Edited.Atoms.Count; i++)
            {
                ar = Edited.Atoms[i];
                dataGridView2.Rows.Add();
                FillDGV(dataGridView2, ar, i,"col");
            }
            checkBoxShared.Checked = Edited.Shared;
        }
        /// <summary>
        /// Заполнить таблицу значениями из атомарного ресурса
        /// </summary>
        /// <param name="dgv">таблица</param>
        /// <param name="ar">ресурс</param>
        /// <param name="i">№ строки</param>
        /// <param name="prefix">Префикс в названии столбца</param>
        private void FillDGV(DataGridView dgv, AtomicRes ar, int i, string prefix)
        {
            dgv[prefix + "Name", i].Value = ar.Name;
            dgv[prefix + "Category", i].Value = ar.Category;
            //допишем доп. параметры
            for (int j = 0; j < ParamNames.Count; j++)
            {
                dgv[prefix + "Param" + j, i].Value = ar.Params[j];
            }
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            Apply();
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.Close();
        }

        private void Apply()
        {
            //инициализируем поля
            Edited.Text = textBoxText.Text;
            Edited.Multiplicity = Convert.ToInt32(numericUpDown1.Value);

            //перепишем вторую таблицу
            Edited.Atoms.Clear();
            AtomicRes ar;
            for (int i = 0; i < dataGridView2.Rows.Count; i++)//по строкам
            {
                ar = new AtomicRes();
                ar.Name = Convert.ToString(dataGridView2["colName", i].Value);
                ar.Category = Convert.ToString(dataGridView2["colCategory", i].Value);
                //перепишем параметры
                for (int j = 0; j < ParamNames.Count; j++)
                {
                    ar.Params.Add(Convert.ToDouble(dataGridView2["colParam" + j, i].Value));
                }
                //добавим атомарный ресурс
                Edited.Atoms.Add(ar);
            }
            //настроим разделяемость
            Edited.Shared = checkBoxShared.Checked;
            Edited.Multiplicity = Convert.ToInt32(numericUpDown1.Value);
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.Close();
        }

        private void treeViewAtomic_Click(object sender, EventArgs e)
        {
            TreeNode tn = treeViewAtomic.SelectedNode;
            TreeNode tc;
            AtomicRes r;
            dataGridView1.Rows.Clear();
            if (tn != null)
            {
                if(tn.Name.Contains("Atomic"))
                {//если выделен узел атомарного ресурса
                    tc = tn.Parent;//его категория
                    //найдем ресурс 
                    r = Categories[tc.Text].Find(delegate(AtomicRes ar) { return ar.Name == tn.Text; });
                    //заполним таблицу
                    dataGridView1.Rows.Add();
                    FillDGV(dataGridView1, r, 0,"Column");
                }
            }
        }

        private void buttonCopy_Click(object sender, EventArgs e)
        {
            //скопируем строку из таблицы 1 в таблицу 2
            if (dataGridView1.Rows.Count > 0)
            {
                DataGridViewRow dr = (dataGridView1.Rows[0].Clone() as DataGridViewRow);
                for (int index = 0; index < dataGridView1.Rows[0].Cells.Count; index++)
                {
                    dr.Cells[index].Value = dataGridView1.Rows[0].Cells[index].Value;
                }
                dataGridView2.Rows.Add(dr);
            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            //просто добавим строку
            int id = dataGridView2.Rows.Add();
            for (int i = 0; i < ParamNames.Count; i++)
            {//заполним значения нулями
                dataGridView2[i + 2, id].Value = 0;
            }
        }

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            if(dataGridView2.SelectedRows.Count == 0)
                return;
            //если они есть, предупредим пользователя
            DialogResult d = MessageBox.Show("Вы уверены, что хотите удалить выделенные строки?", "Предупреждение", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
            if (d == System.Windows.Forms.DialogResult.Yes)
            {
                //удалим
                foreach (DataGridViewRow dr in dataGridView2.SelectedRows)
                {
                    dataGridView2.Rows.Remove(dr);
                }
            }
        }

        private void checkBoxShared_CheckedChanged(object sender, EventArgs e)
        {
            labelMult.Enabled = !checkBoxShared.Checked;
            numericUpDown1.Enabled = !checkBoxShared.Checked;
        }

        private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
        /// <summary>
        /// Проверка, является ли текст числом типа Double. Если нет, выз. ErrorProvider
        /// </summary>
        /// <param name="s">Текстовая строка</param>
        /// <param name="ctr">Элемент управления, которому присвоится ErrorProvider</param>
        /// <returns>ИСТИНА если является double, иначе ЛОЖЬ</returns>
        private bool CheckDouble(string s, Control ctr)
        {
            bool b = true;
            errorProvider1.Clear();
            try
            {
                Convert.ToDouble(s);
            }
            catch
            {
                b = false;
                errorProvider1.SetError(ctr, "В эту ячейку можно ввести только число!");
            }
            return b;
        }

        private void dataGridView2_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if(e.ColumnIndex > 1)
            {//не для первых 2-х колонок, которые строковые
                if (!CheckDouble(Convert.ToString(dataGridView2[e.ColumnIndex, e.RowIndex].Value), dataGridView2 as Control))
                {//если ввели не double
                    dataGridView2[e.ColumnIndex, e.RowIndex].Selected = true;
                }
            }
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void buttonHelp_Click(object sender, EventArgs e)
        {
            string openCHMFile = Application.StartupPath + "\\Справка SAPR-SIM.chm";
            try
            {
                if (!System.IO.File.Exists(openCHMFile))
                    System.IO.File.WriteAllBytes(openCHMFile, global::ModelConfigurator.Properties.Resources.Справка_SAPR_SIM);
            }
            catch
            {
                //если файл есть он не перепишется
            }
            helpProvider1.HelpNamespace = openCHMFile;
            Help.ShowHelp(this, this.helpProvider1.HelpNamespace, HelpNavigator.Topic, "module_2_6_2.htm");
        }
    }
}
